from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from django.contrib import auth
from django.conf import settings
from client import *
from monkey import *
import exceptions

NAME = getattr(settings,'AUTHENTICATION_NAME','django')


def get_wrapper(f,d,username):
    def func(name):
        if name.startswith('_'):
            return f(name)
        try:
            profile = getprofile(d,username)
        except:
            return f(name)
        if name in profile: 
            return profile[name]
        else:
            raise exceptions.AttributeError()
    return func


def set_wrapper(f,d,username):
    def func(name,value):
        try:
            profile = getprofile(d,username)
        except:
            raise Exception('Not able to save user.')
        try:
            profile[name] = value
            setprofile(d,username,profile)
            f(name,value)
        except:
            raise Exception('Not able to set value.')
    return func


class CouchBackend(ModelBackend):
    def create_user(self,username,email,d=None):
        return create_user(username,email,d)
    def authenticate(self,username=None,password=None,token=None):
        try:
            if hasattr(settings,'AUTH_D'):
                d = settings.AUTH_D
            else:
                d = client.authenticate(NAME)
                setattr(settings,'AUTH_D',d)


        except:
            return ModelBackend.authenticate(self,username,password)
        if token:
            ret = callfunc(d,'verify_session',token)
            if ret[0] == 0 and ret[1]:
                em = callfunc(d,'get_account',(username,))
                if em[0] == 0 and 'email' in em[1]:
                    email = em[1]['email']
                else:
                    email = ''
                return self.create_user(username,email,d)
        else:
            if not username or not password:
                return None
            try:
                ret = callfunc(d,'authenticate',(username,password))
            except:
                return None
            if ret[0] == 0 and ret[1]:
                em = callfunc(d,'get_account',(username,))
                if em[0] == 0 and 'email' in em[1]:
                    email = em[1]['email']
                else:
                    email = ''
                return self.create_user(username,email,em[1] if em[0] == 0 else {})
            return None
            
